import pexpect
import datetime
import time
import smtplib
import os
import sys
from email import Encoders
from email.header import Header
from email.mime.text import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from optparse import OptionParser
from ftplib import FTP
import pdb
import json
import subprocess
import socket
from parse_config import Parse
from enum import Enum

SPN1 = '<span style="padding-left:10px;">'
SPN2 = '<span style="padding-left:20px;">'
SPN3 = '<span style="padding-left:30px;">'
SPN4 = '<span style="padding-left:40px;">'
SPN5 = '<span style="padding-left:50px;">'
SPN6 = '<span style="padding-left:60px;">'
SPN7 = '<span style="padding-left:70px;">'


class ExeResultType(Enum):
    EXE_RESULT_TXT = 0
    EXE_RESULT_HTML = 1
    EXE_RESULT_ERROR = 2


class Email:
    sender = "mongo@pachiratech.com"
    senderpass = "0YouUtQMaU71&"
    # receivers = ['asr@pachiratech.com']
    # receivers = ['wangxianwei@pachiratech.com']
    receivers = ['wangxianwei@pachiratech.com', 'sunyanyan@pachiratech.com', 'wangjiamin@pachiratech.com',
                 'zhaomaoxiang@pachiratech.com',
                 'wangxin@pachiratech.com', 'liuwei@pachiratech.com', 'chenyifei@pachiratech.com',
                 'zhangyuhui@pachiratech.com',
                 'mali@pachiratech.com', 'qinyuanyuan@pachiratech.com', 'sunyinping@pachiratech.com',
                 'limenghuan591@pachiratech.com',
                 'yexingxing@pachiratech.com', 'wangwei@pachiratech.com', 'xiaoyanhong@pachiratech.com',
                 'guyisi@pachiratech.com',
                 'siyinjiang@pachiratech.com']
    cclist = []
    # title = "Mongo自动分拣bug，邮件分发测试"
    title = "Mongo自动化测试结果-%s" % (time.strftime("%Y/%m/%d %A"))
    content = None
    attach = []
    parses = None
    reportPath = 'report'
    htmlWebPath = 'htmlWeb'
    failResultPath = 'failResult'
    excuteNum = 1
    trySendNum = 100
    emailReceiver = []
    emailTitle = None
    emailContent = None
    testDataDate = None

    def __init__(self, workspace, report, parses):
        self.NumType = None
        self.workspace = workspace
        self.report = report
        self.parses = parses
        self.currentTime = time.strftime('%Y-%m-%d', time.localtime(time.time()))
        self.emailTitle, self.emailReceiver, self.emailContent = self.getEmailParam()
        with open("%s/solution.json" % workspace, 'r') as fp:
            self.last_report = json.load(fp)
            fp.close()
        return

    def getEmailParam(self):
        emailReceiver = []
        emailTitle = None
        emailContent = None
        title = []
        content = []
        receiver = []
        for parse in self.parses:
            mongoConfig = parse.get_mongoConfig()
            title_ = mongoConfig.get_emailTitle()
            receiver_ = mongoConfig.get_emailReceiver()
            content_ = mongoConfig.get_emailContent()
            self.testDataDate = mongoConfig.getTestDataDate()
            if receiver_ is not None:
                for i in range(0, len(receiver_)):
                    if receiver_[i] is not None and receiver_[i] not in receiver:
                        receiver.append(receiver_[i])
            if title_ is not None:
                title.append(title_)
            if content_ is not None:
                content.append(content_)
        # pdb.set_trace()
        connector = '-'
        connector_ = '<br><br>%s' % SPN2
        if len(title) != 0:
            title__ = connector.join(title)
            emailTitle = "%s-%s" % (title__, time.strftime("%Y/%m/%d %A"))
        if len(content) != 0:
            emailContent = connector_.join(content)
        if len(receiver) != 0:
            emailReceiver = receiver
        return emailTitle, emailReceiver, emailContent

    def __getDifference(self, begin_date, end_date):
        date1 = datetime.datetime.strptime(begin_date, "%Y-%m-%d")
        date2 = datetime.datetime.strptime(end_date, "%Y-%m-%d")
        difference = (date2 - date1).days
        return difference

    def addTitle(self, title):
        self.title = title
        return

    def addContent(self, content):
        self.content = content
        return

    def addAttach(self, attach, name):
        _attach = {'file': attach, 'name': name}
        self.attach.append(_attach)
        return

    def getSolution(self, solutions, solution_name):
        for solution in solutions:
            if solution['solution_name'] == solution_name:
                return solution
        return None

    def getScenarioInfo(self, solution, scene_name):
        if solution is None:
            return 0, 0, 0, 0
        for scenario in solution['solution_report']:
            if scenario['sceneName'] == scene_name:
                return len(scenario['sceneInfo']['suiteInfo']), scenario['sceneInfo']['suiteSummary']['passedNum'], \
                    scenario['sceneInfo']['suiteSummary']['caseNum'], scenario['sceneInfo']['suiteSummary']['failedNum']
        return 0, 0, 0, 0

    def send(self, NumType):
        # pdb.set_trace()
        # self.__sendTxtStyle()
        self.NumType = NumType.value
        if self.NumType == 1:
            self.__failResult()
            self.__webPage()
            if self.testDataDate is not None:
                self.__sendOnlineStyle()
            else:
                self.__sendTableStyle()
        elif self.NumType == 2:
            self.__sendError()

    def __sendPassword(self, cmd):
        self.cmd = cmd
        try:
            child = pexpect.spawn(self.cmd)
            child.expect('.password:')
            child.sendline('Wxry,wdrS@52')
            child.interact()
        except Exception as e:
            print(f"connection timed out or cmd is error: {e}")
            return -1
        return 0

    def __sendError(self):
        self.content = """<!DOCTYPE Html><html lang="en"><html><head><meta charset="UTF-8"></head>"""
        self.content += """<body>"""
        self.content += """<h3>Hi Pachiraers:</h3>"""
        self.content += """<p>%s由于编译错误，本次回归无结果。</p>""" % SPN2
        self.content += "%s      邮件发送者为Mongo，通过python.email模块代理发送，不可直接回复。<br>" % SPN2
        self.content += "<br><br>祝：工作愉快~~<br>"
        self.content += "</body></html>"
        runNum = 0
        while runNum < self.trySendNum:
            ret = self.__doSend()
            if ret == 0:
                break
            runNum += 1
            time.sleep(180)

    def __sendTxtStyle(self):
        # 组织邮件内容
        self.content = "Hi Pachiraers:<br>%s下面是Mongo中%d个solution回归测试结果概述，详细见附件：Mongo_Report_solution_xxx.xml。<br>" % (
        SPN2, len(self.report))
        solutionId = 0
        for solution in self.report:
            solutionId += 1
            solution_name = solution['solution_name']
            solution_report = solution['solution_report']
            scenarioNum = len(solution_report)
            suiteNum = 0
            passedNum = 0
            caseNum = 0
            failedNum = 0

            for scenario in solution_report:
                suiteNum += len(scenario['sceneInfo']['suiteInfo'])
                passedNum += scenario['sceneInfo']['suiteSummary']['passedNum']
                caseNum += scenario['sceneInfo']['suiteSummary']['caseNum']
                failedNum += scenario['sceneInfo']['suiteSummary']['failedNum']

            self.content += "%s%d.测试方案：%s<br>" % (SPN2, solutionId, solution_name)
            self.content += "%s%d.1 solution概述：<br>" % (SPN3, solutionId)
            self.content += "%s测试scenario数量：%d<br>" % (SPN4, scenarioNum)
            self.content += "%s测试suite数量：%d<br>" % (SPN4, suiteNum)
            self.content += "%s失败suite数量：%d<br>" % (SPN4, suiteNum - passedNum)
            self.content += "%s测试case数量：%d<br>" % (SPN4, caseNum)
            self.content += "%s失败case数量：%d<br>" % (SPN4, failedNum)

            self.content += "%s%d.2 具体测试场景概述：<br>" % (SPN3, solutionId)
            scenarioNum = 0
            for scenario in solution_report:
                scenarioNum += 1
                self.content += "%s%d.2.%d 场景（%s）<br>" % (SPN4, solutionId, scenarioNum, scenario['sceneName'])
                suiteSummary = scenario['sceneInfo']['suiteSummary']
                self.content += "%s测试suite数量：%d<br>" % (SPN5, suiteSummary['suiteNum'])
                self.content += "%s失败suite数量：%d<br>" % (SPN5, suiteSummary['suiteNum'] - suiteSummary['passedNum'])
                self.content += "%s测试case数量：%d<br>" % (SPN5, suiteSummary['caseNum'])
                self.content += "%s失败case数量：%d[S->%d A->%d B->%d C->%d]<br>" % (
                SPN5, suiteSummary['failedNum'], suiteSummary['S'], suiteSummary['A'], suiteSummary['B'],
                suiteSummary['C'])
                owner = self.parses[solutionId - 1].getOwner(scenario['sceneName'])

                OWNER = ''
                if owner and len(owner) >= 1:
                    for _owner in owner:
                        if _owner == owner[0]:
                            OWNER += "%s" % _owner
                        else:
                            OWNER += "、%s" % _owner
                else:
                    print("no owner")
                self.content += "%s负责人：%s<br>" % (SPN5, OWNER)

            self.content += "%s%d.3 具体测试结果见附件：Mongo_Report_%s.xml<br>" % (SPN3, solutionId, solution_name)
            self.addAttach("%s/%s/Mongo_Report.xml" % (self.workspace, solution_name),
                           "Mongo_Report_%s.xml" % solution_name)

        # self.content += "%s3.具体测试失败的case单独发送相应owner。<br>" % SPN2
        self.content += "<br><br>%s备注：执行未通过的部分对应的owner(SWE为主，TE辅助)需要进行fix。<br>" % SPN2
        self.content += "%s      邮件发送者为Mongo，通过python.email模块代理发送，不可直接回复。<br>" % SPN2
        self.content += "<br><br>祝：工作愉快~~<br>"
        self.__doSend()

        # 单独发送执行失败的case给具体的owner
        '''
        for scenario in self.report:
            self.receivers = []
            self.cclist = []
            self.content = ""
            suiteSummary = scenario['sceneInfo']['suiteSummary']
            if suiteSummary['failedNum'] > 0 :
                #pdb.set_trace()
                owner = self.parse.getOwner(scenario['sceneName'])

                if owner is not None and len(owner) >= 1:
                    OWNER = ''
                    for _owner in owner:
                        if _owner == owner[0]:
                            OWNER += "%s" % _owner
                        else:
                            OWNER += "、%s" % _owner
                        self.receivers.append("%s@pachiratech.com" % _owner.split('-')[0])
                    self.content += "Hi %s:<br>%s下面是Mongo回归测试结果概述, 详细见附件：Mongo_Report_%s.xml。<br>" % (OWNER, SPN2, scenario['sceneName'])
                    self.content += "%s场景（%s）<br>" % (SPN3, scenario['sceneName'])
                    self.content += "%s测试suite数量：%d<br>" % (SPN4, suiteSummary['suiteNum'])
                    self.content += "%s失败suite数量：%d<br>" % (SPN4, suiteSummary['suiteNum'] - suiteSummary['passedNum'])
                    self.content += "%s测试case数量：%d<br>" % (SPN4, suiteSummary['caseNum'])
                    self.content += "%s失败case数量：%d[S->%d A->%d B->%d C->%d]<br>" % (SPN4, suiteSummary['failedNum'], \
                            suiteSummary['S'], suiteSummary['A'], suiteSummary['B'], suiteSummary['C'])
                    #self.receivers.append("%s@pachiratech.com" % SWE)
                    #self.receivers.append("%s@pachiratech.com" % TE)
                    #self.cclist.append("%s@pachiratech.com" % TE)
                    self.attach = "Mongo_Report_%s.xml" % scenario['sceneName']
                    self.reportPath = "%s/%s" %(self.workspace, scenario['sceneName'])
                    self.__doSend()
                else:
                    print "no owner"
          '''

    def __sendTableStyle(self):
        # 获取版本信息
        for solution in self.report:
            solution_name = solution['solution_name']
            with open("%s/%s/version" % (self.workspace, solution_name), 'r') as fp:
                lines = fp.readlines()
                for line in lines:
                    MongoVersion = line.split('"')[3]
            fp.close()
        # 组织邮件内容
        self.content = """<!DOCTYPE Html><html lang="en"><html><head><meta charset="UTF-8"></head>"""
        self.content += """<body>"""
        self.content += """<h3>Hi Pachiraers:</h3>"""

        if self.emailContent != None:
            self.content += """<br><br>%s%s""" % (SPN2, self.emailContent)
        else:
            self.content += """<p>%s本次回归%d个solution，版本信息：SDK-toyota-875-3.5.61，TestCase-%s，Mongo-%s。</p>""" % \
                            (SPN2, len(self.report), MongoVersion, MongoVersion)
            self.content += """<p>%s当套件未全部通过时，不具备发版条件，除非对应场景负责人能针对未通过套件作出合理解释。""" % SPN2
        self.content += """<p>%s回归测试结果如下:</p>""" % SPN2
        self.content += """<p>"""

        # draw table
        solutionId = 0
        for solution in self.report:
            # pdb.set_trace()
            solutionId += 1
            solution_name = solution['solution_name']
            solution_report = solution['solution_report']
            scenarioNum = len(solution_report)
            suiteNum = 0
            passedNum = 0
            caseNum = 0
            failedNum = 0

            lastSuiteNum = 0
            lastPassedNum = 0
            lastCaseNum = 0
            lastFailedNum = 0

            last_solution = self.getSolution(self.last_report, solution_name)

            # self.content +=  """<h5>%s%d.测试方案：%s</h5>""" % (SPN4, solutionId, solution_name)
            self.content += """<table border="4">"""
            self.content += """<caption>%s</caption>""" % solution_name
            self.content += """<tr>"""
            self.content += """<th>测试场景</th>"""
            self.content += """<th>测试套件数</th>"""
            self.content += """<th>通过套件数</th>"""
            self.content += """<th>测试用例数</th>"""
            self.content += """<th>失败测试用例数</th>"""
            self.content += """<th>总结</th>"""
            self.content += """<th>负责人</th>"""
            self.content += """</tr>"""

            scenarioId = 0
            for scenario in solution_report:
                scenarioId += 1
                _suiteNum = len(scenario['sceneInfo']['suiteInfo'])
                _passedNum = scenario['sceneInfo']['suiteSummary']['passedNum']
                _caseNum = scenario['sceneInfo']['suiteSummary']['caseNum']
                _failedNum = scenario['sceneInfo']['suiteSummary']['failedNum']
                suiteNum += _suiteNum
                passedNum += _passedNum
                caseNum += _caseNum
                failedNum += _failedNum

                _lastSuiteNum, _lastPassedNum, _lastCaseNum, _lastFailedNum = self.getScenarioInfo(last_solution,
                                                                                                   scenario[
                                                                                                       'sceneName'])
                lastSuiteNum += _lastSuiteNum
                lastPassedNum += _lastPassedNum
                lastCaseNum += _lastCaseNum
                lastFailedNum += _lastFailedNum

                owner = self.parses[solutionId - 1].getOwner(scenario['sceneName'])
                curOwner = ''
                if owner and len(owner) >= 1:
                    for _owner in owner:
                        if _owner == owner[0]:
                            curOwner += "%s" % _owner.split('-')[0]
                        else:
                            curOwner += ", %s" % _owner.split('-')[0]
                        receiver = "%s@pachiratech.com" % _owner.split('-')[0]
                        if receiver not in self.receivers:
                            self.receivers.append(receiver)
                else:
                    curOwner = '--'

                self.content += """<tr>"""
                self.content += """<td>%s</td>""" % (scenario['sceneName'])
                # self.content +=  """<td>%d.%s</td>""" % (scenarioId, scenario['sceneName'])
                if _lastSuiteNum != _suiteNum:
                    self.content += """<td align="center">%d->%d</td>""" % (_lastSuiteNum, _suiteNum)
                else:
                    self.content += """<td align="center">%d</td>""" % _suiteNum

                if _lastPassedNum != _passedNum:
                    self.content += """<td align="center">%d->%d</td>""" % (_lastPassedNum, _passedNum)
                else:
                    self.content += """<td align="center">%d</td>""" % _passedNum

                if _lastCaseNum != _caseNum:
                    self.content += """<td align="center">%d->%d</td>""" % (_lastCaseNum, _caseNum)
                else:
                    self.content += """<td align="center">%d</td>""" % _caseNum

                if _lastFailedNum != _failedNum:
                    self.content += """<td align="center">%d->%d</td>""" % (_lastFailedNum, _failedNum)
                else:
                    self.content += """<td align="center">%d</td>""" % _failedNum

                self.content += """<td align="center">--</td>"""
                self.content += """<td align="center">%s</td>""" % curOwner
                self.content += """</tr>"""

            self.content += """<th>测试场景总数:%d</th>""" % scenarioId
            if lastSuiteNum != suiteNum:
                self.content += """<td align="center">%d->%d</td>""" % (lastSuiteNum, suiteNum)
            else:
                self.content += """<td align="center">%d</td>""" % suiteNum

            if lastPassedNum != passedNum:
                self.content += """<td align="center">%d->%d</td>""" % (lastPassedNum, passedNum)
            else:
                self.content += """<td align="center">%d</td>""" % passedNum

            if lastCaseNum != caseNum:
                self.content += """<td align="center">%d->%d</td>""" % (lastCaseNum, caseNum)
            else:
                self.content += """<td align="center">%d</td>""" % caseNum

            if lastFailedNum != failedNum:
                self.content += """<td align="center">%d->%d</td>""" % (lastFailedNum, failedNum)
            else:
                self.content += """<td align="center">%d</td>""" % failedNum

            self.content += """<td align="center" colspan="2">附件 : Mongo_Report_%s.html</td>""" % solution_name
            self.content += """</table><br><br>"""

            self.addAttach("%s/%s/Mongo_Report.html" % (self.workspace, solution_name),
                           "Mongo_Report_%s.html" % solution_name)

        self.content += """<p><a href="file:///\\192.168.131.251\gongxiang\\asr\Mongo\share\%s\%s\%s\htmlweb.html"> \
                            %s详细报告请点此处</a></p>""" % (self.currentTime, self.excuteNum, self.htmlWebPath, SPN2)
        self.content += "<br><br>%s备注：执行未通过的部分对应的owner(SWE为主，TE辅助)需要进行fix。<br>" % SPN2
        self.content += "%s邮件发送者为Mongo，通过python.email模块代理发送，不可直接回复。<br>" % SPN6
        self.content += "%s表格中数据，当和昨天的数据不一致时，会显示出昨天和今天的结果，如：90->100，表示昨天90条，今天100条。<br>" % SPN6
        self.content += "<br><br>祝：工作愉快~~<br>"
        self.content += """</p>"""
        self.content += """</body>"""
        self.content += """</html>"""


        runNum = 0
        while runNum < self.trySendNum:
            ret = self.__doSend()
            if ret == 0:
                break
            runNum += 1
            time.sleep(180)

    def __failResult(self):
        # makedir in gongxiang
        hostaddr = '192.168.131.251'
        username = 'gongxiang'
        password = 'Wxry,wdrS@52'
        port = 21
        remotedir = './asr/Mongo/share/'
        dirList = []
        ftp = FTP()
        try:
            timeout = 10000
            socket.setdefaulttimeout(timeout)
            ftp.set_pasv(True)
            print('>>>>>>Start connecting to the server %s') % hostaddr
            ftp.connect(hostaddr, port)
            print('>>>>>>Successfully connected to the server %s') % hostaddr
            print('>>>>>>Start logging to the server %s') % hostaddr
            ftp.login(username, password)
            print('>>>>>>Successfully logged in to the server %s') % hostaddr
        except:
            print('>>>>>>>logging or connecting to the server failed')
        try:
            ftp.cwd(remotedir)
            print('>>>>>>Successfully changed directory to %s') % remotedir
        except:
            print('>>>>>>Failed to change directory to %s') % remotedir
        try:
            ftp.cwd(self.currentTime)
        except:
            ftp.mkd(self.currentTime)
            ftp.cwd(self.currentTime)
        ftp.dir('.', dirList.append)
        if len(dirList) == 0:
            ftp.mkd(str(self.excuteNum))
        else:
            self.excuteNum = len(dirList) + 1
            ftp.mkd(str(self.excuteNum))
        ftp.cwd(str(self.excuteNum))
        ftp.mkd(self.reportPath)
        ftp.mkd(self.htmlWebPath)
        ftp.mkd(self.failResultPath)
        ftp.close()
        for solution in self.report:
            solution_name = solution['solution_name']
            solution_report = solution['solution_report']
            for scenario in solution_report:
                suiteInfo = sorted(scenario['sceneInfo']['suiteInfo'], key=lambda x: x['suiteID'])
                with open('%s/%s/%s/suites.html' % (self.workspace, solution_name, scenario['sceneName']), 'w') as fp:
                    data = """<!DOCTYPE Html><html lang="en"><html><head><meta charset="UTF-8"></head>"""
                    data += """<body>"""
                    data += """<b>Details of failed cases</b><br>"""
                    for suite in suiteInfo:
                        suite_summary = suite['summary']
                        # write failed suite
                        if len(suite_summary['passed']) == 2:
                            data += '<b>testsuite_%d name="%s"</b>' % (suite['suiteID'], suite['suiteName'])
                            data += '<b> config="%s"</b><br>' % suite['suiteConfig']
                            data += '%scase="%s"' % (SPN3, suite['suiteCaseList'])
                            data += ' tag="%s"<br>' % suite['suiteTag']
                            fp.write(data)
                            # write failed case
                            for caseInfo in suite['caseInfo']:
                                errInfo = caseInfo['errInfo']
                                if len(errInfo) >= 1:
                                    data = '%stestcase name="%s" BugGrade="%s</p1><br>' % \
                                           (SPN3, caseInfo['caseName'], caseInfo['bugGrade'])
                                    for err in errInfo:
                                        data += '%sInput="%s"</p2><br>' % (SPN6, err['input'])
                                        data += '%sActual="%s"</p2><br>' % (SPN6, err['actual'])
                                        data += '%sExpect="%s"</p2><br>' % (SPN6, err['expect'])
                                    fp.write(data)
                                # failed suite summary
                                data = '<p1 class="leftmargin">case_num="%d"</p1>' % (suite_summary['caseNum'])
                                data += ' total_time="%ds"' % suite_summary['totalTime']
                                data += ' failed_num="%d[S->%d A->%d B->%d C->%d]"' % \
                                        (suite_summary['failedNum'], suite_summary['S'], suite_summary['A'], \
                                         suite_summary['B'], suite_summary['C'])
                                data += ' passed="%s"<br>' % suite_summary['passed']
                    data += """</body></html>"""
                    fp.write(data)
                # copy to gongxiang, delete files
                cmd = 'scp %s/%s/%s/suites.html gongxiang@192.168.131.251:/home/gongxiang/asr/Mongo/share/%s/%s/%s/%s_%s_suites.html' % \
                      (self.workspace, solution_name, scenario['sceneName'], self.currentTime, self.excuteNum,
                       self.failResultPath, solution_name, scenario['sceneName'])
                sendNum = 0
                while sendNum < self.trySendNum:
                    ret = self.__sendPassword(cmd)
                    if ret == 0:
                        break
                    sendNum += 1
                    time.sleep(6)
                subprocess.call("rm %s/%s/%s/suites.html" % (self.workspace, solution_name, scenario['sceneName']),
                                shell=True)

    def __sendOnlineStyle(self):
        report_list = []
        report_list.append(self.last_report)
        report_list.append(self.report)
        currentDate = datetime.datetime.now().strftime('%Y-%m-%d')
        # get mongo version
        for solution in self.report:
            solution_name = solution['solution_name']
            with open("%s/%s/version" % (self.workspace, solution_name), 'r') as fp:
                lines = fp.readlines()
                for line in lines:
                    MongoVersion = line.split('"')[3]
            fp.close()

        # email content
        self.content = """<!DOCTYPE Html><html lang="en"><html><head><meta charset="UTF-8"></head>"""
        self.content += """<body>"""
        self.content += """<h3>Hi Pachiraers:</h3>"""
        if self.emailContent != None:
            self.content += """%s%s""" % (SPN2, self.emailContent)
        else:
            self.content += """<p>%s本次回归线上运维测试环境，回归测试结果如下:</p>""" % SPN2
        self.content += """<p>"""

        # draw table head
        self.content += """<table border="1">"""
        self.content += """<tr>"""
        self.content += """<th style="background-color:#FFCCCC">项目</th>"""
        self.content += """<th style="background-color:#FFCCCC">数据日期</th>"""
        self.content += """<th style="background-color:#FFCCCC">测试模块</th>"""
        self.content += """<th style="background-color:#FFCCCC">测试用例数</th>"""
        self.content += """<th style="background-color:#FFCCCC">错误测试用例数</th>"""
        self.content += """<th style="background-color:#FFCCCC">正确率</th>"""
        self.content += """<th style="background-color:#FFCCCC">负责人</th>"""
        self.content += """<th style="background-color:#FFCCCC">版本信息</th>"""
        self.content += """</tr>"""
        duration = ['近半年', '近两周', '近一周']
        for m in range(0, len(report_list)):
            for solution in report_list[m]:
                count = 0
                solution_name = solution['solution_name']
                solution_report = solution['solution_report']
                self.content += """<tr>"""
                if 'lexus' in solution_name:
                    self.content += """<td align="center" rowspan="6">lexus<br>(800B)</td>"""
                elif 'toyota' in solution_name:
                    self.content += """<td align="center" rowspan="6">toyota<br>(875B、891B)</td>"""
                for i in range(0, len(duration)):
                    self.content += """<td rowspan="2" align="center">%s</td>""" % duration[i]
                    for scenario in solution_report:
                        oneWeekCaseNum = 0
                        oneWeekFailedNum = 0
                        twoWeekCaseNum = 0
                        twoWeekFailedNum = 0
                        caseNum = scenario['sceneInfo']['suiteSummary']['caseNum']
                        failedNum = scenario['sceneInfo']['suiteSummary']['failedNum']

                        suiteInfo = sorted(scenario['sceneInfo']['suiteInfo'], key=lambda x: x['suiteID'])
                        # find suite whose date within two weeks and one week
                        for suite in suiteInfo:
                            caseDate = suite['suiteCaseList'].split('/')[-1][0:10]
                            difference = self.__getDifference(caseDate, currentDate)
                            if 0 <= difference <= 7:
                                oneWeekCaseNum += suite['summary']['caseNum']
                                oneWeekFailedNum += suite['summary']['failedNum']
                            if 0 <= difference <= 14:
                                twoWeekCaseNum += suite['summary']['caseNum']
                                twoWeekFailedNum += suite['summary']['failedNum']
                        # draw table data according to different time
                        self.content += """<td align="center">%s</td>""" % (scenario['sceneName'])
                        if i == 0:
                            accuracy = 0
                            if caseNum != 0:
                                accuracy = (1 - failedNum * 1.0 / caseNum * 1.0) * 100
                            self.content += """<td align="center">%d</td>""" % caseNum
                            self.content += """<td align="center">%d</td>""" % failedNum
                            self.content += """<td align="center">%.2f</td>""" % accuracy
                        elif i == 1:
                            accuracy = 0
                            if twoWeekCaseNum != 0:
                                accuracy = (1 - twoWeekFailedNum / twoWeekCaseNum * 1.0) * 100
                            self.content += """<td align="center">%d</td>""" % twoWeekCaseNum
                            self.content += """<td align="center">%d</td>""" % twoWeekFailedNum
                            self.content += """<td align="center">%.2f</td>""" % accuracy
                        elif i == 2:
                            accuracy = 0
                            if oneWeekCaseNum != 0:
                                accuracy = (1 - oneWeekFailedNum / oneWeekCaseNum * 1.0) * 100
                            self.content += """<td align="center">%d</td>""" % oneWeekCaseNum
                            self.content += """<td align="center">%d</td>""" % oneWeekFailedNum
                            self.content += """<td align="center">%.2f</td>""" % accuracy
                        owner = self.parses[0].getOwner(scenario['sceneName'])
                        OWNER = ''
                        if owner and len(owner) >= 1:
                            for _owner in owner:
                                if _owner == owner[0]:
                                    OWNER += "%s" % _owner
                                else:
                                    OWNER += "、%s" % _owner
                        else:
                            print("no owner")
                        self.content += """<td align="center">%s</td>""" % OWNER
                        if count == 0 and 'lexus' in solution_name:
                            self.content += """<td align="center" rowspan="6">asr:chezai-online_20220106_<br>\
                                                 am20210104_lm20220106_<br>utf8_tdnn_dongtai<br>nlu:22-1-19</td>"""
                        elif count == 0 and 'toyota' in solution_name:
                            self.content += """<td align="center" rowspan="6">asr:chezai-online_20220815_<br>am20210910_lianghua_lm20220813_<br>\
                                                 hcc_utf8_dongtai<br>nlu:22-3-10</td>"""
                        count += 1
                        self.content += """</tr>"""
                self.addAttach("%s/%s/Mongo_Report.html" % (self.workspace, solution_name),
                               "Mongo_Report_%s.html" % solution_name)

        self.content += """</table><br><br>"""
        # write email end
        self.content += "<p>%s备注：执行未通过的部分对应的owner(SWE为主，TE辅助)需要进行fix。<br>" % SPN2
        self.content += "%s邮件发送者为Mongo，通过python.email模块代理发送，不可直接回复。<br>" % SPN6
        self.content += "<br><br>祝：工作愉快~~<br>"
        self.content += """</p>"""
        self.content += """</body>"""
        self.content += """</html>"""

        # try to send email 100 times until success
        runNum = 0
        while runNum < self.trySendNum:
            ret = self.__doSend()
            if ret == 0:
                break;
            runNum += 1
            time.sleep(180)

    def __webPage(self):
        # 组织网页内容
        solutionId = 0
        with open('workspace/htmlweb.html', 'w') as files:
            data = """<!DOCTYPE Html><html lang="en"><html><head><meta charset="UTF-8">"""
            data += """<meta name="viewport" content="width=devide-width,initial-scale=1">"""
            data += """<style> * {box-sizing:border-box;}"""
            # set body style
            data += """body {font-family:Arial;margin:0}"""
            # set tips style
            data += """.tips {padding:5px;background:#faebd7;}"""
            # set img style
            data += """.suit img {background-size:contain|cover;width:100%;height:auto;}"""
            # set text style
            data += """.text {padding:5px;background:#87cefa;color:white;}"""
            data += """.text_ {color:blue;}"""
            # set table head style
            data += """.table_h {background:#ffb6c1;color:black;}"""
            # set table data style
            data += """.table_d {background:#fff0f5;color:black;}"""
            data += """</style></head>"""
            data += """<body>"""
            files.write(data)
            data = """<div class="suit"><img src="file:///\\192.168.131.251\gongxiang\\asr\Mongo\share\\mongo.jpg" \
                       alt="Mongo自动化>测试">"""
            data += """</div>"""
            data += """<div class="tips">"""
            data += """<p>"""
            data += """<b>1.什么是solution？</b><br>"""
            data += """%ssolution是根据项目交付特定的测试任务。<br><br>""" % SPN2
            data += """<b>2.什么是测试场景？</b><br>"""
            data += """%s每个测试场景代表了一组完成某个特定测试任务的测试套件的集合，\
                       每一个测试场景可由一个或多个测试套件组成。<br><br>""" % SPN2
            data += """<b>3.什么是测试套件？</b><br>"""
            data += """%s每个测试套件代表了一组完成某个特定测试任务的测试用例的集合，每一个测试套件可由一个或多个测试用例组成。\
                       测试套件包含套件名称、配置文件、测试用例或者标签。<br><br>""" % SPN2
            data += """<b>4.什么是测试用例？</b><br>"""
            data += """%s测试用例代表一个具体的测试动作，每一个用例中包含一个或多个单句。<br>""" % SPN2
            data += """</p></div>"""
            data += """<h2>测试报告总结</h2>"""
            files.write(data)
            for solution in self.report:
                scenarioId = 0
                solutionId += 1
                solution_name = solution['solution_name']
                solution_report = solution['solution_report']
                scenarioNum = len(solution_report)
                suiteNum = 0
                suiteFailedNum = 0
                caseNum = 0
                caseFailedNum = 0
                lastSuiteNum = 0
                lastSuiteFailedNum = 0
                lastCaseNum = 0
                lastCaseFailedNum = 0
                last_solution = self.getSolution(self.last_report, solution_name)
                data = """<table border="4" background-color:#ddd;>"""
                data += """<br>"""
                data += """<caption><b>%s</b></caption>""" % solution_name
                data += """<tr>"""
                data += """<th class="table_h">测试场景</th>"""
                data += """<th class="table_h">测试套件数</th>"""
                data += """<th class="table_h">失败套件数</th>"""
                data += """<th class="table_h">测试用例数</th>"""
                data += """<th class="table_h">失败测试用例数</th>"""
                data += """<th class="table_h">负责人</th>"""
                data += """</tr>"""
                files.write(data)
                for scenario in solution_report:
                    scenarioId += 1
                    _suiteNum = len(scenario['sceneInfo']['suiteInfo'])
                    _suiteFailedNum = scenario['sceneInfo']['suiteSummary']['suiteNum'] - \
                                      scenario['sceneInfo']['suiteSummary']['passedNum']
                    _caseNum = scenario['sceneInfo']['suiteSummary']['caseNum']
                    _caseFailedNum = scenario['sceneInfo']['suiteSummary']['failedNum']
                    suiteNum += _suiteNum
                    suiteFailedNum += _suiteFailedNum
                    caseNum += _caseNum
                    caseFailedNum += _caseFailedNum
                    _lastSuiteNum, _lastSuiteFailedNum, _lastCaseNum, _lastCaseFailedNum = \
                        self.getScenarioInfo(last_solution, scenario['sceneName'])
                    lastSuiteNum += _lastSuiteNum
                    lastSuiteFailedNum += _lastSuiteFailedNum
                    lastCaseNum += _lastCaseNum
                    lastCaseFailedNum += _lastCaseFailedNum
                    owner = self.parses[solutionId - 1].getOwner(scenario['sceneName'])
                    curOwner = ''
                    if owner and len(owner) >= 1:
                        for _owner in owner:
                            if _owner == owner[0]:
                                curOwner += "%s" % _owner.split('-')[0]
                            else:
                                curOwner += ", %s" % _owner.split('-')[0]
                    else:
                        curOwner = '--'
                    data = """<tr>"""
                    data += """<td align="center"  class ="table_d">%s</td>""" % (scenario['sceneName'])
                    if _lastSuiteNum != _suiteNum:
                        data += """<td align="center" class ="table_d">%d->%d</td>""" % (_lastSuiteNum, _suiteNum)
                    else:
                        data += """<td align="center" class ="table_d">%d</td>""" % _suiteNum

                    if _lastSuiteFailedNum != _suiteFailedNum:
                        data += """<td align="center" class ="table_d">%d->%d</td>""" % (
                        _lastSuiteFailedNum, _suiteFailedNum)
                    else:
                        data += """<td align="center" class ="table_d">%d</td>""" % _suiteFailedNum

                    if _lastCaseNum != _caseNum:
                        data += """<td align="center" class ="table_d">%d->%d</td>""" % (_lastCaseNum, _caseNum)
                    else:
                        data += """<td align="center" class ="table_d">%d</td>""" % _caseNum

                    if _lastCaseFailedNum != _caseFailedNum:
                        data += """<div class="text_"> \
                                    <td align="center" class ="table_d"> \
                                    <a href="file:///\\192.168.131.251\gongxiang\\asr\Mongo\share\%s\%s\%s\%s_%s_suites.html">%d->%d \
                                    </a></td></div>""" % (
                        self.currentTime, self.excuteNum, self.failResultPath, solution_name, scenario['sceneName'],
                        _lastCaseFailedNum, _caseFailedNum)
                    else:
                        data += """<div class="text_"> \
                                    <td align="center" class ="table_d"> \
                                    <a href="file:///\\192.168.131.251\gongxiang\\asr\Mongo\share\%s\%s\%s\%s_%s_suites.html">%d \
                                    </a></td></div>""" % (
                        self.currentTime, self.excuteNum, self.failResultPath, solution_name, scenario['sceneName'],
                        _caseFailedNum)

                    data += """<td align="center" class ="table_d">%s</td>""" % curOwner
                    data += """</tr>"""
                    files.write(data)
                data = """<th  class ="table_d">测试场景总数:%d</th>""" % scenarioId
                if lastSuiteNum != suiteNum:
                    data += """<td align="center" class ="table_d">%d->%d</td>""" % (lastSuiteNum, suiteNum)
                else:
                    data += """<td align="center" class ="table_d">%d</td>""" % suiteNum

                if lastSuiteFailedNum != suiteFailedNum:
                    data += """<td align="center" class ="table_d">%d->%d</td>""" % (lastSuiteFailedNum, suiteFailedNum)
                else:
                    data += """<td align="center" class ="table_d">%d</td>""" % suiteFailedNum

                if lastCaseNum != caseNum:
                    data += """<td align="center" class ="table_d">%d->%d</td>""" % (lastCaseNum, caseNum)
                else:
                    data += """<td align="center" class ="table_d">%d</td>""" % caseNum

                if lastCaseFailedNum != caseFailedNum:
                    data += """<td align="center" class ="table_d">%d->%d</td>""" % (lastCaseFailedNum, caseFailedNum)
                else:
                    data += """<td align="center" class ="table_d">%d</td>""" % caseFailedNum
                files.write(data)
                data = """<div class="text_">"""
                if 'sdk' in solution_name:
                    data += """<td align="center" colspan="2" class ="table_d"> \
                                   <a href="file:///\\192.168.131.251\gongxiang\\asr\Mongo\share\%s\%s\%s\Mongo_Report_solution_toyota_sdk.html">solution_toyota_sdk测试报告</a></td>""" % (
                    self.currentTime, self.excuteNum, self.reportPath)
                if 'asr' in solution_name:
                    data += """<td align="center" colspan="2" class ="table_d"> \
                                   <a href="file:///\\192.168.131.251\gongxiang\\asr\Mongo\share\%s\%s\%s\Mongo_Report_solution_toyota_asr.html">solution_toyota_asr测试报告</a></td>""" % (
                    self.currentTime, self.excuteNum, self.reportPath)
                if 'nlu' in solution_name:
                    data += """<td align="center" colspan="2" class ="table_d"> \
                                   <a href="file:///\\192.168.131.251\gongxiang\\asr\Mongo\share\%s\%s\%s\Mongo_Report_solution_toyota_nlu.html">solution_toyota_nlu测试报告</a></td>""" % (
                    self.currentTime, self.excuteNum, self.reportPath)
                data += """</div>"""
                data += """</table><br><br>"""
                files.write(data)
                # copy report to gongxiang
                cmd = 'scp %s/%s/Mongo_Report.html gongxiang@192.168.131.251:/home/gongxiang/asr/Mongo/share/%s/%s/%s/Mongo_Report_%s.html' % \
                      (self.workspace, solution_name, self.currentTime, self.excuteNum, self.reportPath, solution_name)
                sendNum = 0
                while sendNum < self.trySendNum:
                    ret = self.__sendPassword(cmd)
                    if ret == 0:
                        break
                    sendNum += 1
                    time.sleep(6)
            data = """<b>"""
            data += """注意事项"""
            data += """<p>"""
            data += """%s1.当套件未全部通过时，不具备发版条件， 除非对应场景负责人能针对未通过套件作出合理解释。<br>""" % SPN2
            data += """%s2.执行未通过的部分对应的owner(SWE为主，TE辅助)需要进行fix。<br>""" % SPN2
            data += """%s3.邮件发送者为Mongo，通过python.email模块代理发送，不可直接回复。<br>""" % SPN2
            data += """%s4.表格中数据，当和昨天的数据不一致时，会显示出昨天和今天的结果，如：90->100，表示昨天90条，今天100条。<br>""" % SPN2
            data += """%s5.具体报告请点击上方报告链接&#8593;&#8593;&#8593;""" % SPN2
            data += """</p></b>"""
            data += """</body></html>"""
            files.write(data)
        cmd = 'scp workspace/htmlweb.html gongxiang@192.168.131.251:/home/gongxiang/asr/Mongo/share/%s/%s/%s' % (
        self.currentTime, self.excuteNum, self.htmlWebPath)
        sendNum = 0
        while sendNum < self.trySendNum:
            ret = self.__sendPassword(cmd)
            if ret == 0:
                break
            sendNum += 1
            time.sleep(6)
        subprocess.call("rm %s/htmlweb.html" % self.workspace, shell=True)

    def __doSend(self):
        # pdb.set_trace()
        msg = MIMEMultipart()
        if len(self.emailReceiver) > 0:
            self.receivers = self.emailReceiver
        if self.emailTitle is None:
            msg['Subject'] = Header(self.title, 'utf-8')
        else:
            msg['Subject'] = Header(self.emailTitle, 'utf-8')
        msg['From'] = Header(self.sender, 'utf-8')
        msg['To'] = str(self.receivers)
        if len(self.cclist) != 0:
            msg['CC'] = str(self.cclist)
        if len(self.cclist) != 0:
            msg['CC'] = str(self.cclist)

        message = MIMEText(self.content, 'html', 'utf-8')
        msg.attach(message)

        for attach in self.attach:
            att1 = MIMEText(open(attach['file'], 'rb').read(), 'base64', 'utf-8')
            att1["Content-Type"] = 'application/octet-stream'
            att1["Content-Disposition"] = 'attachment; filename="%s"' % attach['name']
            msg.attach(att1)
        try:
            smtpObj = smtplib.SMTP()
            smtpObj.connect("smtp.pachiratech.com")
        except Exception as e:
            print("error when connect the smtpserver with the given sender server:smtp.pachiratech.com !")
            print(e)
            return -1

        try:
            smtpObj.login(self.sender, self.senderpass)
        except Exception as e:
            print("error when connect the smtpserver with the given username and password !")
            print(e)
            return -1

        try:
            smtpObj.sendmail(self.sender, self.receivers, msg.as_string())
            print("邮件发送成功")
        except smtplib.SMTPException:
            print("Error: 无法发送邮件")
            return -1

        return 0
